package com.example.hospital;

import com.example.hospital.exception.*;
import com.example.hospital.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


import com.example.hospital.pojo.*;
import com.example.hospital.util.ConsoleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;

import org.fusesource.jansi.Ansi;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@Slf4j
@SpringBootApplication
public class SpringbootConsoleApplication implements CommandLineRunner {

    @Autowired
    private UserService userService;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private PositionService positionService;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private LeaveService leaveService;

    @Autowired
    private ShiftSwapService shiftSwapService;

    @Autowired
    private SystemLogService systemLogService;

    @Autowired
    private GlobalExceptionHandler exceptionHandler;

    private User currentUser;

    //调用run方法；准备spring的上下文，完成容器的初始化，创建，加载等。会在不同的时机触发监听器的不同事件...
    public static void main(String[] args) {
        SpringApplication.run(SpringbootConsoleApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        try {
            login();
            if (currentUser != null) {
                mainMenu();
            }
        } catch (LoginException e) {
            // 使用异常处理器处理异常
            exceptionHandler.handleLoginException(e);
        }
        ConsoleUtils.printColored("感谢使用医院排班管理系统，再见！", Ansi.Color.GREEN);
        System.exit(0);
    }


    private void login() {

        int loginTimes = 3;
        /*登录逻辑：每次登录有三次机会，第三次登录失败(用户名或密码错误),抛出登陆时异常*/
        while (currentUser == null) {
            ConsoleUtils.printColored("\n=== 医院排班管理系统 ===", Ansi.Color.CYAN);
            String username = ConsoleUtils.readLine("用户名: ");
            String password = ConsoleUtils.readPassword("密码: "); // 隐藏密码输入，如可能

            User user = userService.login(username, password);
            if (user != null) {
                currentUser = user;
                ConsoleUtils.printColored("登录成功！欢迎, " + currentUser.getUsername(), Ansi.Color.GREEN);
                // 记录登录日志
                SystemLog log = new SystemLog();
                log.setUserId(currentUser.getId());
                log.setAction("用户登录");
                log.setIpAddress("127.0.0.1"); // 示例IP地址
                systemLogService.logAction(log);
            } else {
                --loginTimes;
                if(loginTimes == 0) {
                    throw new LoginException("登录失败次数已超过限制！");
                }
                ConsoleUtils.printColored("登录失败，用户名或密码错误。", Ansi.Color.RED);
            }
        }
    }

    // TODO 主界面菜单
    private void mainMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 主菜单 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 用户管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 科室管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("3. 职位管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("4. 排班管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("5. 请假管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("6. 调班管理", Ansi.Color.WHITE);
            ConsoleUtils.printColored("7. 报表与统计", Ansi.Color.WHITE);
            ConsoleUtils.printColored("8. 系统日志", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 退出", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                        userManagementMenu();
                    } else {
                        ConsoleUtils.printColored("没有权限访问用户管理。", Ansi.Color.RED);
                    }
                    break;
                case 2:
                    if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                        departmentManagementMenu();
                    } else {
                        ConsoleUtils.printColored("没有权限访问科室管理。", Ansi.Color.RED);
                    }
                    break;
                case 3:
                    if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                        positionManagementMenu();
                    } else {
                        ConsoleUtils.printColored("没有权限访问职位管理。", Ansi.Color.RED);
                    }
                    break;
                case 4:
                    scheduleManagementMenu();
                    break;
                case 5:
                    leaveManagementMenu();
                    break;
                case 6:
                    shiftSwapManagementMenu();
                    break;
                case 7:
                    reportAndStatisticsMenu();
                    break;
                case 8:
                    if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                        systemLogMenu();
                    } else {
                        ConsoleUtils.printColored("没有权限访问系统日志。", Ansi.Color.RED);
                    }
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    // 以下部分将详细介绍每个功能模块的实现

    // TODO 用户管理菜单
    private void userManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 用户管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 添加用户", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看所有用户", Ansi.Color.WHITE);
            ConsoleUtils.printColored("3. 修改用户", Ansi.Color.WHITE);
            ConsoleUtils.printColored("4. 删除用户", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    try {
                        addUser();
                    } catch (UserServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleUserServiceException(e);
                    }
                    break;
                case 2:
                    viewAllUsers();
                    break;
                case 3:
                    try {
                        updateUser();
                    } catch (UserServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleUserServiceException(e);
                    }
                    break;
                case 4:
                    try {
                        deleteUser();
                    } catch (UserServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleUserServiceException(e);
                    }
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void addUser() {
        ConsoleUtils.printColored("\n=== 添加用户 ===", Ansi.Color.YELLOW);
        String username = ConsoleUtils.readLine("用户名: ");
        String password = ConsoleUtils.readLine("密码: ");
        String role = ConsoleUtils.readLine("角色 (ADMIN, DOCTOR, NURSE): ").toUpperCase();
        String email = ConsoleUtils.readLine("邮箱: ");
        String phone = ConsoleUtils.readLine("电话: ");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setRole(role);
        user.setEmail(email);
        user.setPhone(phone);

        //判断当前用户是否存在(若已经存在使用姓名进行判断)
        if( userService.getUserByName(user.getUsername()) != null){
            throw new UserServiceException("The current user already exists!");
        }
        userService.registerUser(user);

        ConsoleUtils.printColored("用户添加成功！", Ansi.Color.GREEN);

        // 记录日志
        SystemLog log = new SystemLog();
        log.setUserId(currentUser.getId());
        log.setAction("添加用户: " + user.getUsername());
        log.setIpAddress("127.0.0.1"); // 示例IP地址
        systemLogService.logAction(log);

        ConsoleUtils.pause();
    }

    private void viewAllUsers() {
        ConsoleUtils.printColored("\n=== 所有用户 ===", Ansi.Color.YELLOW);
        List<User> users = userService.getAllUsers();
        System.out.printf("%-5s %-15s %-10s %-25s %-15s\n", "ID", "用户名", "角色", "邮箱", "电话");
        for (User user : users) {
            System.out.printf("%-5d %-15s %-10s %-25s %-15s\n",
                    user.getId(), user.getUsername(), user.getRole(), user.getEmail(), user.getPhone());
        }
        ConsoleUtils.pause();
    }

    private void updateUser() {
        ConsoleUtils.printColored("\n=== 修改用户 ===", Ansi.Color.YELLOW);
        int userId = ConsoleUtils.readInt("请输入用户ID: ");
        User user = userService.getUserById(userId);
        if (user == null) {
            throw new UserServiceException("updateUser:user not found!");
        }

        String username = ConsoleUtils.readLine("用户名 [" + user.getUsername() + "]: ");
        String password = ConsoleUtils.readLine("密码 [不修改请留空]: ");
        String role = ConsoleUtils.readLine("角色 [" + user.getRole() + "]: ").toUpperCase();
        String email = ConsoleUtils.readLine("邮箱 [" + user.getEmail() + "]: ");
        String phone = ConsoleUtils.readLine("电话 [" + user.getPhone() + "]: ");

        if (!username.isEmpty()) user.setUsername(username);
        if (!password.isEmpty()) user.setPassword(password);
        if (!role.isEmpty()) user.setRole(role);
        if (!email.isEmpty()) user.setEmail(email);
        if (!phone.isEmpty()) user.setPhone(phone);

        userService.updateUser(user);
        ConsoleUtils.printColored("用户更新成功！", Ansi.Color.GREEN);

        ConsoleUtils.pause();
    }

    private void deleteUser() {
        ConsoleUtils.printColored("\n=== 删除用户 ===", Ansi.Color.YELLOW);
        int userId = ConsoleUtils.readInt("请输入用户ID: ");
        User user = userService.getUserById(userId);
        if (user == null) {
             throw new UserServiceException("deleteUser:user not found!");
        }

        String confirmation = ConsoleUtils.readLine("确认删除用户 " + user.getUsername() + " 吗？(y/n): ");
        if (confirmation.equalsIgnoreCase("y")) {
            userService.deleteUser(userId);
            ConsoleUtils.printColored("用户删除成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("删除操作已取消。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    // TODO 科室管理菜单
    private void departmentManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 科室管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 添加科室", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看所有科室", Ansi.Color.WHITE);
            ConsoleUtils.printColored("3. 修改科室", Ansi.Color.WHITE);
            ConsoleUtils.printColored("4. 删除科室", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    try {
                        addDepartment();
                    } catch (DepartmentServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleDepartmentServiceException(e);
                    }
                    break;
                case 2:
                    viewAllDepartments();
                    break;
                case 3:
                    try {
                        updateDepartment();
                    } catch (DepartmentServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleDepartmentServiceException(e);
                    }
                    break;
                case 4:
                    try {
                        deleteDepartment();
                    } catch (DepartmentServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleDepartmentServiceException(e);
                    }
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void addDepartment() {
        ConsoleUtils.printColored("\n=== 添加科室 ===", Ansi.Color.YELLOW);
        String name = ConsoleUtils.readLine("科室名称: ");

        Department dept = new Department();
        dept.setName(name);

        departmentService.addDepartment(dept);

        ConsoleUtils.printColored("科室添加成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void viewAllDepartments() {
        ConsoleUtils.printColored("\n=== 所有科室 ===", Ansi.Color.YELLOW);
        List<Department> departments = departmentService.getAllDepartments();
        System.out.printf("%-5s %-20s\n", "ID", "科室名称");
        for (Department dept : departments) {
            System.out.printf("%-5d %-20s\n", dept.getId(), dept.getName());
        }
        ConsoleUtils.pause();
    }

    private void updateDepartment() {
        ConsoleUtils.printColored("\n=== 修改科室 ===", Ansi.Color.YELLOW);
        int deptId = ConsoleUtils.readInt("请输入科室ID: ");
        Department dept = departmentService.getDepartmentById(deptId);
        if (dept == null) {
            throw new DepartmentServiceException("updateDepartment: department not found!");
        }

        String name = ConsoleUtils.readLine("科室名称 [" + dept.getName() + "]: ");
        if (!name.isEmpty()) {
            dept.setName(name);
            departmentService.updateDepartment(dept);
            ConsoleUtils.printColored("科室更新成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("没有修改任何内容。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    private void deleteDepartment() {
        ConsoleUtils.printColored("\n=== 删除科室 ===", Ansi.Color.YELLOW);
        int deptId = ConsoleUtils.readInt("请输入科室ID: ");
        Department dept = departmentService.getDepartmentById(deptId);
        if (dept == null) {
            throw new DepartmentServiceException("deleteDepartment: department not found!");
        }

        String confirmation = ConsoleUtils.readLine("确认删除科室 " + dept.getName() + " 吗？(y/n): ");
        if (confirmation.equalsIgnoreCase("y")) {
            departmentService.deleteDepartment(deptId);
            ConsoleUtils.printColored("科室删除成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("删除操作已取消。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    // TODO 职位管理菜单
    private void positionManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 职位管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 添加职位", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看所有职位", Ansi.Color.WHITE);
            ConsoleUtils.printColored("3. 修改职位", Ansi.Color.WHITE);
            ConsoleUtils.printColored("4. 删除职位", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    try {
                        addPosition();
                    } catch (PositionServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handlePositionServiceException(e);
                    }
                    break;
                case 2:
                    viewAllPositions();
                    break;
                case 3:
                    try {
                        updatePosition();
                    } catch (PositionServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handlePositionServiceException(e);
                    }
                    break;
                case 4:
                    try {
                        deletePosition();
                    } catch (PositionServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handlePositionServiceException(e);
                    }
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void addPosition() {
        ConsoleUtils.printColored("\n=== 添加职位 ===", Ansi.Color.YELLOW);
        String name = ConsoleUtils.readLine("职位名称: ");

        Position position = new Position();
        position.setName(name);

        positionService.addPosition(position);
        ConsoleUtils.printColored("职位添加成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void viewAllPositions() {
        ConsoleUtils.printColored("\n=== 所有职位 ===", Ansi.Color.YELLOW);
        List<Position> positions = positionService.getAllPositions();
        System.out.printf("%-5s %-20s\n", "ID", "职位名称");
        for (Position pos : positions) {
            System.out.printf("%-5d %-20s\n", pos.getId(), pos.getName());
        }
        ConsoleUtils.pause();
    }

    private void updatePosition() {
        ConsoleUtils.printColored("\n=== 修改职位 ===", Ansi.Color.YELLOW);
        int posId = ConsoleUtils.readInt("请输入职位ID: ");
        Position pos = positionService.getPositionById(posId);
        if (pos == null) {
            throw new PositionServiceException("updatePosition: position not found!");
        }

        String name = ConsoleUtils.readLine("职位名称 [" + pos.getName() + "]: ");
        if (!name.isEmpty()) {
            pos.setName(name);
            positionService.updatePosition(pos);
            ConsoleUtils.printColored("职位更新成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("没有修改任何内容。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    private void deletePosition() {
        ConsoleUtils.printColored("\n=== 删除职位 ===", Ansi.Color.YELLOW);
        int posId = ConsoleUtils.readInt("请输入职位ID: ");
        Position pos = positionService.getPositionById(posId);
        if (pos == null) {
            throw new PositionServiceException("deletePosition: position not found!");
        }

        String confirmation = ConsoleUtils.readLine("确认删除职位 " + pos.getName() + " 吗？(y/n): ");
        if (confirmation.equalsIgnoreCase("y")) {
            positionService.deletePosition(posId);
            ConsoleUtils.printColored("职位删除成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("删除操作已取消。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    //TODO 排班管理菜单
    private void scheduleManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 排班管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 添加排班", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看排班", Ansi.Color.WHITE);
            ConsoleUtils.printColored("3. 修改排班", Ansi.Color.WHITE);
            ConsoleUtils.printColored("4. 删除排班", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    try {
                        addSchedule();
                    } catch (UserServiceException e) {
                        // 使用异常处理器处理异常
                        exceptionHandler.handleUserServiceException(e);
                    }catch (DepartmentServiceException e){
                        exceptionHandler.handleDepartmentServiceException(e);
                    }catch (PositionServiceException e){
                        exceptionHandler.handlePositionServiceException(e);
                    }catch (DateFormatErrorException e){
                        exceptionHandler.handleDateFormatErrorException(e);
                    }catch (ScheduleServiceException e){
                        exceptionHandler.handleScheduleServiceException(e);
                    }
                    break;
                case 2:
                    viewSchedules();
                    break;
                case 3:
                    try {
                        updateSchedule();
                    } catch (ScheduleServiceException e) {

                        exceptionHandler.handleScheduleServiceException(e);
                    } catch (DateFormatErrorException e){

                        exceptionHandler.handleDateFormatErrorException(e);
                    }
                    break;
                case 4:
                    try {
                        deleteSchedule();
                    } catch (ScheduleServiceException e) {

                        exceptionHandler.handleScheduleServiceException(e);
                    }
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void addSchedule() {
        ConsoleUtils.printColored("\n=== 添加排班 ===", Ansi.Color.YELLOW);
        int userId = ConsoleUtils.readInt("用户ID: ");
        User user = userService.getUserById(userId);
        if (user == null) {
            throw new UserServiceException("addSchedule: user not found!");
        }

        int departmentId = ConsoleUtils.readInt("科室ID: ");
        Department dept = departmentService.getDepartmentById(departmentId);
        if (dept == null) {
             throw new DepartmentServiceException("addSchedule: department not found!");
        }

        int positionId = ConsoleUtils.readInt("职位ID: ");
        Position pos = positionService.getPositionById(positionId);
        if (pos == null) {
             throw new PositionServiceException("addSchedule: position not found!");
        }

        String dateStr = ConsoleUtils.readLine("班次日期 (yyyy-MM-dd): ");
        String shiftType = ConsoleUtils.readLine("班次类型 (早班、晚班等): ");

        Date shiftDate;
        try {
            shiftDate = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (Exception e) {
            throw new DateFormatErrorException("addSchedule: wrong date format!");
        }

        Schedule schedule = new Schedule();
        schedule.setUserId(userId);
        schedule.setDepartmentId(departmentId);
        schedule.setPositionId(positionId);
        schedule.setShiftDate(shiftDate);
        schedule.setShiftType(shiftType);

        //判断排班是否冲突
        List<Schedule> allSchedules = scheduleService.getAllSchedules();
        for (Schedule s : allSchedules){
            if(s.getDepartmentId() == schedule.getDepartmentId() &&
                s.getShiftType().equals(schedule.getShiftType()) &&
                s.getShiftDate().equals(schedule.getShiftDate())&&
                s.getShiftType().equals(schedule.getShiftType())
            ){
                log.info("冲突的用户id:{}",s.getUserId());
                throw new ScheduleServiceException("addSchedule:Scheduling conflict!");
            }
        }

        scheduleService.createSchedule(schedule);
        ConsoleUtils.printColored("排班添加成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void viewSchedules() {
        ConsoleUtils.printColored("\n=== 查看排班 ===", Ansi.Color.YELLOW);
        if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
            List<Schedule> schedules = scheduleService.getAllSchedules();
            printSchedules(schedules);
        } else {
            List<Schedule> schedules = scheduleService.getSchedulesByUserId(currentUser.getId());
            printSchedules(schedules);
        }
        ConsoleUtils.pause();
    }

    private void printSchedules(List<Schedule> schedules) {
        System.out.printf("%-5s %-10s %-10s %-15s %-10s\n", "ID", "用户ID", "科室ID", "日期", "班次类型");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (Schedule s : schedules) {
            System.out.printf("%-5d %-10d %-10d %-15s %-10s\n",
                    s.getId(),
                    s.getUserId(),
                    s.getDepartmentId(),
                    sdf.format(s.getShiftDate()),
                    s.getShiftType());
        }
    }

    private void updateSchedule() {
        ConsoleUtils.printColored("\n=== 修改排班 ===", Ansi.Color.YELLOW);
        int scheduleId = ConsoleUtils.readInt("请输入排班ID: ");
        Schedule schedule = scheduleService.getScheduleById(scheduleId);
        if (schedule == null) {
           throw new ScheduleServiceException("updateSchedule: schedule not found!");
        }

        String userIdStr = ConsoleUtils.readLine("用户ID [" + schedule.getUserId() + "]: ");
        String deptIdStr = ConsoleUtils.readLine("科室ID [" + schedule.getDepartmentId() + "]: ");
        String posIdStr = ConsoleUtils.readLine("职位ID [" + schedule.getPositionId() + "]: ");
        String dateStr = ConsoleUtils.readLine("班次日期 (yyyy-MM-dd) [" +
                new SimpleDateFormat("yyyy-MM-dd").format(schedule.getShiftDate()) + "]: ");
        String shiftType = ConsoleUtils.readLine("班次类型 [" + schedule.getShiftType() + "]: ");

        if (!userIdStr.isEmpty()) {
            int userId = Integer.parseInt(userIdStr);
            schedule.setUserId(userId);
        }
        if (!deptIdStr.isEmpty()) {
            int deptId = Integer.parseInt(deptIdStr);
            schedule.setDepartmentId(deptId);
        }
        if (!posIdStr.isEmpty()) {
            int posId = Integer.parseInt(posIdStr);
            schedule.setPositionId(posId);
        }
        if (!dateStr.isEmpty()) {
            try {
                Date shiftDate = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
                schedule.setShiftDate(shiftDate);
            } catch (Exception e) {
                throw new DateFormatErrorException("updateSchedule:wrong date format!");
            }
        }
        if (!shiftType.isEmpty()) {
            schedule.setShiftType(shiftType);
        }

        scheduleService.updateSchedule(schedule);
        ConsoleUtils.printColored("排班更新成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void deleteSchedule() {
        ConsoleUtils.printColored("\n=== 删除排班 ===", Ansi.Color.YELLOW);
        int scheduleId = ConsoleUtils.readInt("请输入排班ID: ");
        Schedule schedule = scheduleService.getScheduleById(scheduleId);
        if (schedule == null) {
            throw new ScheduleServiceException("deleteSchedule: schedule not found!");
        }

        String confirmation = ConsoleUtils.readLine("确认删除排班ID " + scheduleId + " 吗？(y/n): ");
        if (confirmation.equalsIgnoreCase("y")) {
            scheduleService.deleteSchedule(scheduleId);
            ConsoleUtils.printColored("排班删除成功！", Ansi.Color.GREEN);
        } else {
            ConsoleUtils.printColored("删除操作已取消。", Ansi.Color.YELLOW);
        }
        ConsoleUtils.pause();
    }

    //TODO 请假管理菜单
    private void leaveManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 请假管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 提交请假申请", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看我的请假申请", Ansi.Color.WHITE);
            if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                ConsoleUtils.printColored("3. 审批请假申请", Ansi.Color.WHITE);
                ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);
            } else {
                ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);
            }

            int choice = ConsoleUtils.readInt("请选择操作: ");

            if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                switch (choice) {
                    case 1:
                        try {
                            applyLeave();
                        } catch (DateFormatErrorException e) {
                            exceptionHandler.handleDateFormatErrorException(e);
                        }
                        break;
                    case 2:
                        viewMyLeaves();
                        break;
                    case 3:
                        approveOrRejectLeave();
                        break;
                    case 0:
                        return;
                    default:
                        ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
                }
            } else {
                switch (choice) {
                    case 1:
                        try {
                            applyLeave();
                        } catch (DateFormatErrorException e) {

                            exceptionHandler.handleDateFormatErrorException(e);
                        }
                        break;
                    case 2:
                        viewMyLeaves();
                        break;
                    case 0:
                        return;
                    default:
                        ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
                }
            }
        }
    }

    private void applyLeave() {
        ConsoleUtils.printColored("\n=== 提交请假申请 ===", Ansi.Color.YELLOW);
        String startDateStr = ConsoleUtils.readLine("开始日期 (yyyy-MM-dd): ");
        String endDateStr = ConsoleUtils.readLine("结束日期 (yyyy-MM-dd): ");
        String reason = ConsoleUtils.readLine("请假原因: ");

        Date startDate, endDate;
        try {
            startDate = new SimpleDateFormat("yyyy-MM-dd").parse(startDateStr);
            endDate = new SimpleDateFormat("yyyy-MM-dd").parse(endDateStr);
        } catch (Exception e) {
             throw new DateFormatErrorException("applyLeave: wrong date format!");
        }

        LeaveRequest leave = new LeaveRequest();
        leave.setUserId(currentUser.getId());
        leave.setStartDate(startDate);
        leave.setEndDate(endDate);
        leave.setReason(reason);

        leaveService.applyLeave(leave);
        ConsoleUtils.printColored("请假申请提交成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void viewMyLeaves() {
        ConsoleUtils.printColored("\n=== 我的请假申请 ===", Ansi.Color.YELLOW);
        List<LeaveRequest> leaves = leaveService.getLeavesByUserId(currentUser.getId());
        System.out.printf("%-5s %-15s %-15s %-20s %-10s\n", "ID", "开始日期", "结束日期", "原因", "状态");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (LeaveRequest leave : leaves) {
            System.out.printf("%-5d %-15s %-15s %-20s %-10s\n",
                    leave.getId(),
                    sdf.format(leave.getStartDate()),
                    sdf.format(leave.getEndDate()),
                    leave.getReason(),
                    leave.getStatus());
        }
        ConsoleUtils.pause();
    }

    private void approveOrRejectLeave() {
        ConsoleUtils.printColored("\n=== 审批请假申请 ===", Ansi.Color.YELLOW);
        List<LeaveRequest> allLeaves = leaveService.getAllLeaves();
        System.out.printf("%-5s %-10s %-15s %-15s %-20s %-10s\n", "ID", "用户ID", "开始日期", "结束日期", "原因", "状态");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (LeaveRequest leave : allLeaves) {
            System.out.printf("%-5d %-10d %-15s %-15s %-20s %-10s\n",
                    leave.getId(),
                    leave.getUserId(),
                    sdf.format(leave.getStartDate()),
                    sdf.format(leave.getEndDate()),
                    leave.getReason(),
                    leave.getStatus());
        }

        int leaveId = ConsoleUtils.readInt("请输入要审批的请假申请ID: ");
        LeaveRequest leave = leaveService.getAllLeaves().stream()
                .filter(l -> l.getId().equals(leaveId))
                .findFirst()
                .orElse(null);

        if (leave == null) {
            ConsoleUtils.printColored("请假申请不存在！", Ansi.Color.RED);
            ConsoleUtils.pause();
            return;
        }

        if (!leave.getStatus().equals("待审批")) {
            ConsoleUtils.printColored("此请假申请已处理过。", Ansi.Color.YELLOW);
            ConsoleUtils.pause();
            return;
        }

        String decision = ConsoleUtils.readLine("批准还是拒绝？(a/r): ");
        if (decision.equalsIgnoreCase("a")) {
            leaveService.approveLeave(leaveId);
            ConsoleUtils.printColored("请假申请已批准。", Ansi.Color.GREEN);
        } else if (decision.equalsIgnoreCase("r")) {
            leaveService.rejectLeave(leaveId);
            ConsoleUtils.printColored("请假申请已拒绝。", Ansi.Color.YELLOW);
        } else {
            ConsoleUtils.printColored("无效的选项。", Ansi.Color.RED);
        }
        ConsoleUtils.pause()    ;
    }

    //TODO 调班管理菜单
    private void shiftSwapManagementMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 调班管理 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 提交调班申请", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 查看我的调班申请", Ansi.Color.WHITE);
            if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                ConsoleUtils.printColored("3. 审批调班申请", Ansi.Color.WHITE);
                ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);
            } else {
                ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);
            }

            int choice = ConsoleUtils.readInt("请选择操作: ");

            if (currentUser.getRole().equalsIgnoreCase("ADMIN")) {
                switch (choice) {
                    case 1:
                        try {
                            applyShiftSwap();
                        } catch (DateFormatErrorException e) {
                            exceptionHandler.handleDateFormatErrorException(e);
                        } catch (UserServiceException e){
                            exceptionHandler.handleUserServiceException(e);
                        }
                        break;
                    case 2:
                        viewMyShiftSwaps();
                        break;
                    case 3:
                        approveOrRejectShiftSwap();
                        break;
                    case 0:
                        return;
                    default:
                        ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
                }
            } else {
                switch (choice) {
                    case 1:
                        try {
                            applyShiftSwap();
                        } catch (DateFormatErrorException e) {

                            exceptionHandler.handleDateFormatErrorException(e);
                        } catch (UserServiceException e){

                            exceptionHandler.handleUserServiceException(e);
                        }
                        break;
                    case 2:
                        viewMyShiftSwaps();
                        break;
                    case 0:
                        return;
                    default:
                        ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
                }
            }
        }
    }

    private void applyShiftSwap() {
        ConsoleUtils.printColored("\n=== 提交调班申请 ===", Ansi.Color.YELLOW);
        int receiverId = ConsoleUtils.readInt("被调班的用户ID: ");
        User receiver = userService.getUserById(receiverId);
        if (receiver == null) {
           throw new UserServiceException("applyShiftSwap: user not found!");
        }
        String dateStr = ConsoleUtils.readLine("调班日期 (yyyy-MM-dd): ");
        Date date;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (Exception e) {
             throw new DateFormatErrorException("applyShiftSwap: wrong date format!");
        }

        ShiftSwap swap = new ShiftSwap();
        swap.setRequesterId(currentUser.getId());
        swap.setReceiverId(receiverId);
        swap.setDate(date);

        shiftSwapService.applyShiftSwap(swap);
        ConsoleUtils.printColored("调班申请提交成功！", Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void viewMyShiftSwaps() {
        ConsoleUtils.printColored("\n=== 我的调班申请 ===", Ansi.Color.YELLOW);
        List<ShiftSwap> swaps = shiftSwapService.getShiftsByUserId(currentUser.getId());
        System.out.printf("%-5s %-12s %-12s %-15s %-10s\n", "ID", "申请人ID", "接收人ID", "日期", "状态");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (ShiftSwap swap : swaps) {
            System.out.printf("%-5d %-12d %-12d %-15s %-10s\n",
                    swap.getId(),
                    swap.getRequesterId(),
                    swap.getReceiverId(),
                    sdf.format(swap.getDate()),
                    swap.getStatus());
        }
        ConsoleUtils.pause();
    }

    private void approveOrRejectShiftSwap() {
        ConsoleUtils.printColored("\n=== 审批调班申请 ===", Ansi.Color.YELLOW);
        List<ShiftSwap> allSwaps = shiftSwapService.getAllShiftSwaps();
        System.out.printf("%-5s %-12s %-12s %-15s %-10s\n", "ID", "申请人ID", "接收人ID", "日期", "状态");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (ShiftSwap swap : allSwaps) {
            System.out.printf("%-5d %-12d %-12d %-15s %-10s\n",
                    swap.getId(),
                    swap.getRequesterId(),
                    swap.getReceiverId(),
                    sdf.format(swap.getDate()),
                    swap.getStatus());
        }

        int swapId = ConsoleUtils.readInt("请输入要审批的调班申请ID: ");
        ShiftSwap swap = shiftSwapService.getAllShiftSwaps().stream()
                .filter(s -> s.getId().equals(swapId))
                .findFirst()
                .orElse(null);

        if (swap == null) {
            ConsoleUtils.printColored("调班申请不存在！", Ansi.Color.RED);
            ConsoleUtils.pause();
            return;
        }

        if (!swap.getStatus().equals("待审批")) {
            ConsoleUtils.printColored("此调班申请已处理过。", Ansi.Color.YELLOW);
            ConsoleUtils.pause();
            return;
        }

        String decision = ConsoleUtils.readLine("批准还是拒绝？(a/r): ");
        if (decision.equalsIgnoreCase("a")) {
            shiftSwapService.approveShiftSwap(swapId);
            ConsoleUtils.printColored("调班申请已批准。", Ansi.Color.GREEN);
        } else if (decision.equalsIgnoreCase("r")) {
            shiftSwapService.rejectShiftSwap(swapId);
            ConsoleUtils.printColored("调班申请已拒绝。", Ansi.Color.YELLOW);
        } else {
            ConsoleUtils.printColored("无效的选项。", Ansi.Color.RED);
        }
        ConsoleUtils.pause();
    }

    //TODO 报表与统计菜单
    private void reportAndStatisticsMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 报表与统计 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 查看排班统计", Ansi.Color.WHITE);
            ConsoleUtils.printColored("2. 导出排班报表", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    viewScheduleStatistics();
                    break;
                case 2:
                    exportScheduleReport();
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void viewScheduleStatistics() {
        ConsoleUtils.printColored("\n=== 排班统计 ===", Ansi.Color.YELLOW);
        List<Schedule> schedules = scheduleService.getAllSchedules();
        int totalSchedules = schedules.size();
        long doctorsOnDuty = schedules.stream().filter(s -> userService.getUserById(s.getUserId()).getRole().equalsIgnoreCase("DOCTOR")).count();
        long nursesOnDuty = schedules.stream().filter(s -> userService.getUserById(s.getUserId()).getRole().equalsIgnoreCase("NURSE")).count();

        ConsoleUtils.printColored("总排班数: " + totalSchedules, Ansi.Color.GREEN);
        ConsoleUtils.printColored("医生排班数: " + doctorsOnDuty, Ansi.Color.GREEN);
        ConsoleUtils.printColored("护士排班数: " + nursesOnDuty, Ansi.Color.GREEN);
        ConsoleUtils.pause();
    }

    private void exportScheduleReport() {
        ConsoleUtils.printColored("\n=== 导出排班报表 ===", Ansi.Color.YELLOW);
        // 这里只是示例，可以实现导出为CSV或其他格式
        // 这里简单保存为文本文件
        List<Schedule> schedules = scheduleService.getAllSchedules();
        try (java.io.FileWriter writer = new java.io.FileWriter("schedule_report.txt")) {
            writer.write(String.format("%-5s %-10s %-10s %-15s %-10s\n", "ID", "用户ID", "科室ID", "日期", "班次类型"));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (Schedule s : schedules) {
                writer.write(String.format("%-5d %-10d %-10d %-15s %-10s\n",
                        s.getId(),
                        s.getUserId(),
                        s.getDepartmentId(),
                        sdf.format(s.getShiftDate()),
                        s.getShiftType()));
            }
            ConsoleUtils.printColored("排班报表已导出到 schedule_report.txt", Ansi.Color.GREEN);
        } catch (Exception e) {
            ConsoleUtils.printColored("导出失败：" + e.getMessage(), Ansi.Color.RED);
        }
        ConsoleUtils.pause();
    }

    //TODO 系统日志菜单
    private void systemLogMenu() {
        while (true) {
            ConsoleUtils.printColored("\n=== 系统日志 ===", Ansi.Color.YELLOW);
            ConsoleUtils.printColored("1. 查看所有日志", Ansi.Color.WHITE);
            ConsoleUtils.printColored("0. 返回主菜单", Ansi.Color.WHITE);

            int choice = ConsoleUtils.readInt("请选择操作: ");

            switch (choice) {
                case 1:
                    viewAllLogs();
                    break;
                case 0:
                    return;
                default:
                    ConsoleUtils.printColored("无效的选项，请重新选择。", Ansi.Color.RED);
            }
        }
    }

    private void viewAllLogs() {
        ConsoleUtils.printColored("\n=== 所有系统日志 ===", Ansi.Color.YELLOW);
        List<SystemLog> logs = systemLogService.getAllLogs();
        System.out.printf("%-5s %-10s %-30s %-20s %-15s\n", "ID", "用户ID", "操作", "时间", "IP地址");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (SystemLog log : logs) {
            System.out.printf("%-5d %-10d %-30s %-20s %-15s\n",
                    log.getId(),
                    log.getUserId(),
                    log.getAction(),
                    sdf.format(log.getTimestamp()),
                    log.getIpAddress());
        }
        ConsoleUtils.pause();
    }
}
